package ihm;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

import reservation.Billet;
import reservation.Client;
import reservation.Serveur;
import reservation.Trajet;
import algorithme.Dijkstra;
import algorithme.Option;
import data.Classe;
import data.Condition;
import data.Couchette;
import data.Repas;
import data.TypePassager;
import data.Ville;
import data.VilleHelper;

/**
 * Interface pour le client
 * 
 * @author Cyril GORRIERI
 * 
 */
public class InterfaceClient extends Interface {
	private Client client;

	public InterfaceClient(Client c) {
		this.client = c;
	}

	@Override
	public void process(Command command) {
		switch (command.getCommandWord()) {
		case PRINT:
			this.print(command);
			break;
		case RESERVE:
			this.reserve();
			break;
		case UNRESERVE:
			this.unreserve(command.getSecondWord());
			break;
		case BILLETS:
			this.billets();
			break;
		default:
			printHelp();
			break;
		}
	}

	/**
	 * Supprime un billet
	 * @param nom de la resa
	 */
	private void unreserve(String nom) {
		Scanner in = new Scanner(System.in);
		if(nom == null) {
			System.out.println("Erreur: Veuillez entrer un nom !");
			return;
		}
		List<Billet> billets = client.getBillets();
		Billet choix = null;
		Iterator<Billet> it = billets.iterator();
		while(it.hasNext() && choix == null) {
			Billet b = it.next();
			if(b.getClient().equals(client) && b.getNom().equals(nom)) {
				System.out.println("Ce billet ? [1] Oui, [Autre] Nom");
				int reponse = recupererNum(in);
				if(reponse == 1) {
					choix = b;
					Serveur.getInstance().delete(choix);
				}
			} else {
				it.remove();
			}	
		}
		if(billets.isEmpty()) {
			System.out.println("Il n'y a pas de billet à ce nom la !");
		} else {
			System.out.println("Il y a plusieurs billets veuillez choisir le n° de trajet auquel il correspond !");
		}
		if(billets.size() > 1) {
			System.out.println("Il y a plusieurs billets veuillez choisir le n° de trajet auquel il correspond !");
			
		}
	}

	private void billets() {
		List<Billet> billets = client.getBillets();
		System.out.println("*** Vos billets ***");
		for(Billet b : billets) {
			System.out.println(b);
		}
	}

	private void reserve() {
		Scanner in = new Scanner(System.in);
		Ville start, stop;
		System.out.println("*** Reserver ***");
		/* Ville de départ */
		do {
			System.out.println("Ville de départ: ");
			VilleHelper.showAll();
			System.out.print(">> ");
			start = VilleHelper.getVille(in.nextLine());
		} while (start == Ville.UNKNOWN);

		/* Ville d'arrivée */
		do {
			System.out
					.println("Ville d'arrivée (différente de la ville de départ): ");
			VilleHelper.showAll();
			System.out.print(">> ");
			stop = VilleHelper.getVille(in.nextLine());
		} while (stop == Ville.UNKNOWN || stop == start);

		/* Critère de recherche */
		int critere;
		do {
			System.out
					.println("Critère de recherche: [0] Moins cher, [1] Plus rapide");
			System.out.print(">> ");
			try {
				critere = Integer.parseInt(in.nextLine());
			} catch (Exception e) {
				critere = -1;
			}
		} while (critere != 0 && critere != 1);

		/* Combien de personne */
		int nbPersonne;
		do {
			System.out.println("Pour combien de personne:");
			System.out.print(">> ");
			try {
				nbPersonne = Integer.parseInt(in.nextLine());
			} catch (Exception e) {
				nbPersonne = -1;
			}
		} while (nbPersonne <= 0);

		/* On recupere le meilleur chemin, direct ou indirect */
		int source = start.getRang();
		int destination = stop.getRang();
		List<Trajet> trajets = Dijkstra.recupererCheminOptimal(source, destination, critere == 0 ? Option.PRIX : Option.TEMPS);
		if (trajets.size() == 0) {
			System.out
					.println("Il n'y a pas de trajet direct ou indirect entre ces deux villes !");
			return;
		}
		int prixTotal = 0;
		StringBuilder sb = new StringBuilder();
		Trajet t;
		for (int i = 0; i < trajets.size(); i++) {
			t = trajets.get(i);
			if (t.getPlacesRestantes() > nbPersonne) {
				sb.append("\n#### " + (i + 1) + " ####\n");
				sb.append(t.toString());
				sb.append("\nPrix: " + t.calculerPrix() * nbPersonne + "\n");
				prixTotal += t.calculerPrix() * nbPersonne;
			} else {
				System.out
						.println("Desole: Il n'y a pas assez de place dans l'un des trajets");
				return;
			}
		}
		sb.append("\n###########\nPRIX TOTAL: " + prixTotal + " pour "
				+ trajets.size() + " trajet(s)");
		System.out.println(sb.toString());

		/* Valider la reservation */
		int valider;
		System.out.println("valider cet itinerair: [1] Oui, [Autre] Non");
		System.out.print(">> ");
		try {
			valider = Integer.parseInt(in.nextLine());
		} catch (Exception e) {
			valider = -1;
		}
		if (valider != 1)
			return;

		List<String> noms = new ArrayList<String>();
		for (int i = 1; i <= nbPersonne; i++) {
			System.out.println("Entrer le nom et prenom de la personne n°" + i);
			System.out.print(">> ");
			noms.add(in.nextLine());
		}

		List<Billet> billets = new ArrayList<Billet>();
		Repas repas;
		boolean fumeur;
		TypePassager type;
		Classe classe;
		Condition condition;
		Couchette couchette;
		for (String nom : noms) {
			System.out.println("# Choix des options pour " + nom + " #");
			repas = recupereRepas(in);
			fumeur = recupereFumeur(in);
			type = recupereTypePassager(in);
			classe = recupereClasse(in);
			condition = recupereCondition(in);
			couchette = recupereCouchette(in);
			for(Trajet tr : trajets) {
				Billet billet = new Billet(tr, client, nom, repas, fumeur, type, classe, condition, couchette);
				if(client.demanderPossibiliteReservation(billet) == false) {
					System.out.println("Erreur: le billet ne peut etre reservé !");
				} else {
					billets.add(billet);
				}
			}
		}
		prixTotal = 0;
		for(Billet b : billets) {
			client.demanderReservation(b);
			prixTotal += b.calculerPrix();
		}
		System.out.println("###### Prix total des billet : "+ prixTotal+ "######");
	}

	private Repas recupereRepas(Scanner in) {
		System.out.println("> Repas:");
		Repas[] values = Repas.values();
		System.out.print("[0] "+values[0].toString1());
		for (int i = 1; i < values.length; i++) {
			System.out.print(", ["+i+"] "+values[i].toString1());
		}
		System.out.println(", [Autre] Pas de repas");
		System.out.print(">> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			return values[res];
		} catch(Exception e) {
			return Repas.RIEN;
		}
	}
	
	private boolean recupereFumeur(Scanner in) {
		System.out.println("> fumeur:");
		System.out.println("[0] Oui, [Autre] Non");
		System.out.print(">> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			if(res == 1) return true;
			else return false;
		} catch(Exception e) {
			return false;
		}
	}
	
	private TypePassager recupereTypePassager(Scanner in) {
		System.out.println("> Type de passager:");
		TypePassager[] values = TypePassager.values();
		System.out.print("[0] "+values[0].toString1());
		for (int i = 1; i < values.length; i++) {
			System.out.print(", ["+i+"] "+values[i].toString1());
		}
		System.out.print("\n>> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			return values[res];
		} catch(Exception e) {
			return TypePassager.NORMAL;
		}
	}
	
	private Classe recupereClasse(Scanner in) {
		System.out.println("> Classe:");
		Classe[] values = Classe.values();
		System.out.print("[0] "+values[0].toString1());
		for (int i = 1; i < values.length; i++) {
			System.out.print(", ["+i+"] "+values[i].toString1());
		}
		System.out.print("\n>> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			return values[res];
		} catch(Exception e) {
			return Classe.SECONDE;
		}
	}
	
	private Condition recupereCondition(Scanner in) {
		System.out.println("> Classe:");
		Condition[] values = Condition.values();
		System.out.print("[0] "+values[0].toString1());
		for (int i = 1; i < values.length; i++) {
			System.out.print(", ["+i+"] "+values[i].toString1());
		}
		System.out.print("\n>> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			return values[res];
		} catch(Exception e) {
			return Condition.DEFINITIF;
		}
	}
	
	private Couchette recupereCouchette(Scanner in) {
		System.out.println("> Classe:");
		Couchette[] values = Couchette.values();
		System.out.print("[0] "+values[0].toString1());
		for (int i = 1; i < values.length; i++) {
			System.out.print(", ["+i+"] "+values[i].toString1());
		}
		System.out.print("\n>> ");
		try {
			int res = Integer.parseInt(in.nextLine());
			return values[res];
		} catch(Exception e) {
			return Couchette.FAUTEUIL;
		}
	}

	@Override
	protected void goodBye() {
		System.out.println("## Aurevoir et à Bientot ##");
	}

	@Override
	protected void presentation() {
		System.out.println("********* Client *********");
		System.out.println("Tapez une commande ou 'help' pour l'aide.");
	}

	@Override
	protected void printHelp() {
		super.printHelp();
		System.out.println("- Chercher: search [transport | trajet]");
		System.out.println("- Afficher mes billets: billets");
	}
}
